import Util from '../Util';

export default class DeviceMessage {
    public static TYPE_CLIPBOARD = 0;
    public static TYPE_PUSH_RESPONSE = 101;

    public static readonly MAGIC_BYTES_MESSAGE = Util.stringToUtf8ByteArray('scrcpy_message');

    constructor(public readonly type: number, protected readonly buffer: Uint8Array) {}

    public static fromBuffer(data: ArrayBuffer): DeviceMessage {
        const magicSize = this.MAGIC_BYTES_MESSAGE.length;
        // const buffer = Buffer.from(data, magicSize, data.byteLength - magicSize);
        // const type = buffer.readUInt8(0);
        const buffer = new Uint8Array(data, magicSize, data.byteLength - magicSize);

        // Node 的 buffer.readUInt8(0) 等价于：
        const type = buffer[0];
		console.log(buffer);
        return new DeviceMessage(type, buffer);
    }

    public getText(): string {
        if (this.type !== DeviceMessage.TYPE_CLIPBOARD) {
            throw TypeError(`Wrong message type: ${this.type}`);
        }
        if (!this.buffer) {
            throw Error('Empty buffer');
        }

        let offset = 1;
        const view = new DataView(this.buffer.buffer, this.buffer.byteOffset, this.buffer.byteLength);
        const length = view.getInt32(offset, false); // big-endian
        offset += 4;

        const textBytes = this.buffer.subarray(offset, offset + length);
        return Util.utf8ByteArrayToString(textBytes);
    }

    public getPushStats(): { id: number; code: number } {
        if (this.type !== DeviceMessage.TYPE_PUSH_RESPONSE) {
            throw TypeError(`Wrong message type: ${this.type}`);
        }
        if (!this.buffer) {
            throw Error('Empty buffer');
        }

        const view = new DataView(this.buffer.buffer, this.buffer.byteOffset, this.buffer.byteLength);
        const id = view.getInt16(1, false);  // big-endian
        const code = view.getInt8(3);
        return { id, code };
    }

    public toString(): string {
        let desc: string;
        if (this.type === DeviceMessage.TYPE_CLIPBOARD && this.buffer) {
            desc = `, text=[${this.getText()}]`;
        } else {
            // Uint8Array 没有 join，需要转为数组
            desc = this.buffer ? `, buffer=[${Array.from(this.buffer).join(',')}]` : '';
        }
        return `DeviceMessage{type=${this.type}${desc}}`;
    }
}
